package emby.expr;

import emby.EmbyRuntime;
import emby.err.TypeError;
import emby.lang.Scope;
import emby.overload.OverloadCallable;
import emby.writer.IEmbyCodifier;

/**
 * The AST representation of a function call expression.
 * @author Justin
 */
public class Call extends Expression {

	private static final long serialVersionUID = -6268345841448344296L;
	Expression operator;
	Expression[] operands;
	public Call(Expression _operator, Expression... _operands){
		operator = _operator;
		operands = _operands;
	}

	public Object eval(Scope s){
		if(EmbyRuntime.echo){
			emby.util.Print.println("Calling function "+operator+" on (", operands.length, " args) ",operands);
			emby.util.Print.tab();
		}
		//eval operator
		Object op = operator.eval(s);
		OverloadCallable f = null;
		if( op instanceof OverloadCallable){
			f = (OverloadCallable) op;
		}else{
			throw new TypeError(operator.getLine(),op+" is not callable");
		}

		//eval the operands
		Object[] args = new Object[operands.length];
		for(int i = 0; i< operands.length; i++){
			args[i] = operands[i].eval(s);
		}

		//call the operator with the operands
		Object result = f.execute(getLine(),s,args);
		if(EmbyRuntime.echo){
			emby.util.Print.untab();
			emby.util.Print.println("Result of call: "+result);
		}
		return result;
	}

	public String toString(){
		return "{Call expression : "+operator+"}";
	}
	
	public void codify(IEmbyCodifier ec){
		ec.fncall(operator, operands);
	}
}
